<template>
  <div class="training-container">
    <n-card class="training-card">
      <template #header>
        <div class="card-header">
          <h1>AI模型训练</h1>
          <div class="header-actions">
            <n-button @click="startTraining" type="primary" :disabled="!canStartTraining || isTraining">
              <template #icon>
                <n-icon>
                  <FlashOutline />
                </n-icon>
              </template>
              开始训练
            </n-button>
            <n-button @click="goBack">
              <template #icon>
                <n-icon>
                  <ArrowBackOutline />
                </n-icon>
              </template>
              返回
            </n-button>
          </div>
        </div>
      </template>
      
      <div class="content-layout">
        <div class="settings-section">
          <h3>训练设置</h3>
          <n-form
            :model="trainingForm"
            label-placement="left"
            label-width="120"
          >
            <n-form-item label="模型名称" path="modelName">
              <n-input v-model:value="trainingForm.modelName" placeholder="输入模型名称" />
            </n-form-item>
            
            <n-form-item label="训练类型" path="trainingType">
              <n-select
                v-model:value="trainingForm.trainingType"
                :options="trainingTypeOptions"
              />
            </n-form-item>
            
            <n-form-item label="训练数据" path="dataSource">
              <n-upload
                v-model:file-list="trainingForm.fileList"
                directory-dnd
                :max="10"
                :custom-request="customRequest"
                @change="handleUploadChange"
              >
                <n-upload-dragger>
                  <div style="padding: 20px">
                    <n-icon size="48" :depth="3">
                      <CloudUploadOutline />
                    </n-icon>
                    <n-text style="font-size: 16px">
                      拖放文件或点击此处上传训练素材
                    </n-text>
                    <n-p depth="3" style="margin: 8px 0 0 0">
                      支持图片、文本和动作数据
                    </n-p>
                  </div>
                </n-upload-dragger>
              </n-upload>
            </n-form-item>
            
            <n-form-item label="训练轮次" path="epochs">
              <n-input-number
                v-model:value="trainingForm.epochs"
                :min="1"
                :max="100"
              />
            </n-form-item>
            
            <n-form-item label="学习率" path="learningRate">
              <n-select
                v-model:value="trainingForm.learningRate"
                :options="learningRateOptions"
              />
            </n-form-item>
            
            <n-divider />
            
            <n-form-item label="处理位置">
              <n-radio-group v-model:value="trainingForm.processingLocation">
                <n-space>
                  <n-radio value="local">本地处理</n-radio>
                  <n-radio value="cloud">云端处理</n-radio>
                </n-space>
              </n-radio-group>
            </n-form-item>
            
            <n-form-item label="高级选项">
              <n-switch v-model:value="showAdvancedOptions" />
            </n-form-item>
            
            <div v-if="showAdvancedOptions">
              <n-form-item label="批次大小" path="batchSize">
                <n-select
                  v-model:value="trainingForm.batchSize"
                  :options="batchSizeOptions"
                />
              </n-form-item>
              
              <n-form-item label="优化器" path="optimizer">
                <n-select
                  v-model:value="trainingForm.optimizer"
                  :options="optimizerOptions"
                />
              </n-form-item>
              
              <n-form-item label="模型架构" path="architecture">
                <n-select
                  v-model:value="trainingForm.architecture"
                  :options="architectureOptions"
                />
              </n-form-item>
            </div>
            
            <n-divider />
            
            <n-form-item label="训练备注" path="notes">
              <n-input
                v-model:value="trainingForm.notes"
                type="textarea"
                placeholder="输入训练备注信息..."
                :autosize="{ minRows: 3, maxRows: 5 }"
              />
            </n-form-item>
          </n-form>
        </div>
        
        <div class="progress-section">
          <div v-if="isTraining">
            <h3>训练进度</h3>
            <div class="progress-info">
              <n-progress
                type="line"
                :percentage="trainingProgress.percentage"
                :processing="trainingProgress.percentage < 100"
                :indicator-placement="'inside'"
              />
              
              <div class="progress-stats">
                <div class="stat-item">
                  <div class="stat-label">当前轮次</div>
                  <div class="stat-value">{{ trainingProgress.currentEpoch }} / {{ trainingForm.epochs }}</div>
                </div>
                <div class="stat-item">
                  <div class="stat-label">已用时间</div>
                  <div class="stat-value">{{ formatTime(trainingProgress.timeElapsed) }}</div>
                </div>
                <div class="stat-item">
                  <div class="stat-label">预计剩余时间</div>
                  <div class="stat-value">{{ formatTime(trainingProgress.timeRemaining) }}</div>
                </div>
              </div>
              
              <n-divider />
              
              <div class="metrics-charts">
                <div class="chart-container">
                  <h4>损失值</h4>
                  <div class="chart-placeholder">
                    <!-- 这里将放置损失值图表 -->
                    图表占位符
                  </div>
                </div>
                
                <div class="chart-container">
                  <h4>准确率</h4>
                  <div class="chart-placeholder">
                    <!-- 这里将放置准确率图表 -->
                    图表占位符
                  </div>
                </div>
              </div>
              
              <div class="training-logs">
                <h4>训练日志</h4>
                <n-scrollbar style="max-height: 200px;">
                  <div class="log-container">
                    <div v-for="(log, index) in trainingLogs" :key="index" class="log-item">
                      <span class="log-time">{{ log.time }}</span>
                      <span :class="'log-level log-level-' + log.level">{{ log.level }}</span>
                      <span class="log-message">{{ log.message }}</span>
                    </div>
                  </div>
                </n-scrollbar>
              </div>
              
              <div class="control-buttons">
                <n-button @click="pauseTraining" :disabled="!isTraining || isPaused">
                  <template #icon>
                    <n-icon>
                      <PauseOutline />
                    </n-icon>
                  </template>
                  暂停
                </n-button>
                <n-button @click="resumeTraining" :disabled="!isTraining || !isPaused">
                  <template #icon>
                    <n-icon>
                      <PlayOutline />
                    </n-icon>
                  </template>
                  继续
                </n-button>
                <n-button @click="stopTraining" :disabled="!isTraining" type="error">
                  <template #icon>
                    <n-icon>
                      <StopOutline />
                    </n-icon>
                  </template>
                  停止训练
                </n-button>
              </div>
            </div>
          </div>
          
          <div v-else class="models-list">
            <h3>我的训练模型</h3>
            
            <div v-if="trainedModels.length > 0">
              <n-list hoverable>
                <n-list-item v-for="model in trainedModels" :key="model.id">
                  <n-thing :title="model.name" :description="formatDate(model.createdAt)">
                    <template #avatar>
                      <n-avatar :style="{ backgroundColor: getRandomColor(model.id) }">
                        {{ model.name.substring(0, 1).toUpperCase() }}
                      </n-avatar>
                    </template>
                    
                    <template #description>
                      <div class="model-meta">
                        <n-tag :type="model.status === 'ready' ? 'success' : 'warning'">
                          {{ getStatusText(model.status) }}
                        </n-tag>
                        <span class="model-type">{{ getTypeText(model.type) }}</span>
                        <span class="model-meta-item">训练于 {{ formatDate(model.createdAt) }}</span>
                      </div>
                      <div class="model-description">{{ model.description }}</div>
                    </template>
                    
                    <template #footer>
                      <div class="model-actions">
                        <n-button size="small" @click="useModel(model)">使用</n-button>
                        <n-button size="small" @click="exportModel(model)">导出</n-button>
                        <n-button size="small" @click="deleteModel(model)" type="error">删除</n-button>
                      </div>
                    </template>
                  </n-thing>
                </n-list-item>
              </n-list>
            </div>
            
            <n-empty description="暂无训练模型" v-else>
              <template #extra>
                <n-button @click="showOnboarding">查看训练教程</n-button>
              </template>
            </n-empty>
            
            <n-divider />
            
            <div class="training-tips">
              <h4>训练小贴士</h4>
              <ul>
                <li>高质量的训练数据对模型效果至关重要</li>
                <li>为获得最佳效果，建议上传至少50张相关图片或10分钟动作数据</li>
                <li>训练时间取决于数据量和设置的轮次</li>
                <li>如果模型效果不理想，可以尝试调整学习率和增加训练轮次</li>
              </ul>
            </div>
          </div>
        </div>
      </div>
    </n-card>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, computed } from 'vue'
import { useRouter } from 'vue-router'
import { useMessage } from 'naive-ui'
import {
  NCard,
  NButton,
  NIcon,
  NSpace,
  NForm,
  NFormItem,
  NInput,
  NInputNumber,
  NSelect,
  NSwitch,
  NRadioGroup,
  NRadio,
  NDivider,
  NUpload,
  NUploadDragger,
  NProgress,
  NScrollbar,
  NEmpty,
  NList,
  NListItem,
  NThing,
  NTag,
  NAvatar,
  NP,
  NText
} from 'naive-ui'
import {
  FlashOutline,
  ArrowBackOutline,
  CloudUploadOutline,
  PauseOutline,
  PlayOutline,
  StopOutline
} from '@vicons/ionicons5'

const router = useRouter()
const message = useMessage()

// 训练表单
const trainingForm = reactive({
  modelName: '',
  trainingType: 'character',
  fileList: [],
  epochs: 10,
  learningRate: 0.001,
  processingLocation: 'cloud',
  batchSize: 32,
  optimizer: 'adam',
  architecture: 'standard',
  notes: ''
})

// 高级选项显示状态
const showAdvancedOptions = ref(false)

// 训练状态
const isTraining = ref(false)
const isPaused = ref(false)

// 训练进度
const trainingProgress = reactive({
  percentage: 0,
  currentEpoch: 0,
  timeElapsed: 0, // 秒
  timeRemaining: 0 // 秒
})

// 训练日志
const trainingLogs = ref([
  { time: '12:01:05', level: 'info', message: '初始化训练环境...' },
  { time: '12:01:10', level: 'info', message: '加载训练数据: 100张图片' },
  { time: '12:01:15', level: 'info', message: '开始训练，总轮次: 10' },
  { time: '12:01:25', level: 'info', message: '轮次 1/10 完成，损失值: 0.723' },
  { time: '12:01:35', level: 'warning', message: '检测到学习率可能过高' }
])

// 已训练模型列表
const trainedModels = ref([
  {
    id: 1,
    name: '卡通人物风格',
    type: 'character',
    status: 'ready',
    description: '基于200张卡通角色图片训练的模型，适合生成Q版人物角色。',
    createdAt: new Date(Date.now() - 7 * 24 * 60 * 60 * 1000),
    epochs: 20,
    accuracy: 0.92
  },
  {
    id: 2,
    name: '场景转换器',
    type: 'scene',
    status: 'ready',
    description: '专门用于生成古风场景描述的模型，适合古装剧、武侠风格作品。',
    createdAt: new Date(Date.now() - 3 * 24 * 60 * 60 * 1000),
    epochs: 15,
    accuracy: 0.88
  },
  {
    id: 3,
    name: '动作生成器',
    type: 'action',
    status: 'training',
    description: '动作捕捉数据训练模型，用于生成流畅自然的人物动作序列。',
    createdAt: new Date(Date.now() - 12 * 60 * 60 * 1000),
    epochs: 30,
    accuracy: 0.75
  }
])

// 选项数据
const trainingTypeOptions = [
  { label: '角色模型', value: 'character' },
  { label: '场景模型', value: 'scene' },
  { label: '动作模型', value: 'action' },
  { label: '对话模型', value: 'dialogue' }
]

const learningRateOptions = [
  { label: '0.0001 (保守)', value: 0.0001 },
  { label: '0.001 (推荐)', value: 0.001 },
  { label: '0.01 (激进)', value: 0.01 }
]

const batchSizeOptions = [
  { label: '8 (低内存)', value: 8 },
  { label: '16', value: 16 },
  { label: '32 (推荐)', value: 32 },
  { label: '64 (高性能)', value: 64 }
]

const optimizerOptions = [
  { label: 'Adam (推荐)', value: 'adam' },
  { label: 'SGD', value: 'sgd' },
  { label: 'RMSprop', value: 'rmsprop' },
  { label: 'Adagrad', value: 'adagrad' }
]

const architectureOptions = [
  { label: '标准', value: 'standard' },
  { label: '轻量级', value: 'lightweight' },
  { label: '高精度', value: 'highprecision' },
  { label: '定制', value: 'custom' }
]

// 计算是否可以开始训练
const canStartTraining = computed(() => {
  return trainingForm.modelName.trim() !== '' && 
         trainingForm.fileList.length > 0 && 
         trainingForm.epochs > 0
})

// 自定义上传请求
const customRequest = ({ file, onFinish, onError }) => {
  // 模拟上传过程
  setTimeout(() => {
    // 在实际应用中，这里会有真正的文件上传逻辑
    if (Math.random() > 0.1) {
      onFinish()
    } else {
      onError()
    }
  }, 1000)
}

// 处理上传变化
const handleUploadChange = (options: any) => {
  console.log('Upload changed', options)
  // 在实际应用中，这里会有处理上传文件的逻辑
}

// 开始训练
const startTraining = () => {
  if (!canStartTraining.value) {
    message.warning('请完善训练设置')
    return
  }
  
  isTraining.value = true
  isPaused.value = false
  trainingProgress.percentage = 0
  trainingProgress.currentEpoch = 0
  trainingProgress.timeElapsed = 0
  trainingProgress.timeRemaining = trainingForm.epochs * 30 // 假设每轮需要30秒
  
  message.success('训练已开始')
  
  // 模拟训练进度更新
  const interval = setInterval(() => {
    if (isPaused.value) return
    
    trainingProgress.timeElapsed += 1
    trainingProgress.timeRemaining -= 1
    
    // 更新当前轮次和进度
    const epochProgress = trainingProgress.timeElapsed / (trainingProgress.timeElapsed + trainingProgress.timeRemaining)
    trainingProgress.currentEpoch = Math.min(
      Math.floor(epochProgress * trainingForm.epochs) + 1,
      trainingForm.epochs
    )
    trainingProgress.percentage = Math.min(
      Math.round(epochProgress * 100),
      100
    )
    
    // 添加日志
    if (trainingProgress.timeElapsed % 10 === 0) {
      const date = new Date()
      const timeString = `${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}`
      
      trainingLogs.value.unshift({
        time: timeString,
        level: 'info',
        message: `轮次 ${trainingProgress.currentEpoch}/${trainingForm.epochs} 进行中，损失值: ${(1 - epochProgress).toFixed(3)}`
      })
    }
    
    // 完成训练
    if (trainingProgress.percentage >= 100) {
      clearInterval(interval)
      
      trainingLogs.value.unshift({
        time: new Date().toLocaleTimeString(),
        level: 'info',
        message: '训练完成！正在保存模型...'
      })
      
      setTimeout(() => {
        isTraining.value = false
        message.success('训练已完成')
        
        // 添加到模型列表
        trainedModels.value.unshift({
          id: Date.now(),
          name: trainingForm.modelName,
          type: trainingForm.trainingType,
          status: 'ready',
          description: trainingForm.notes || `使用${trainingForm.trainingType}类型数据训练的模型。`,
          createdAt: new Date(),
          epochs: trainingForm.epochs,
          accuracy: 0.8 + Math.random() * 0.15
        })
      }, 2000)
    }
  }, 1000)
}

// 暂停训练
const pauseTraining = () => {
  if (!isTraining.value || isPaused.value) return
  
  isPaused.value = true
  message.info('训练已暂停')
}

// 继续训练
const resumeTraining = () => {
  if (!isTraining.value || !isPaused.value) return
  
  isPaused.value = false
  message.info('训练已继续')
}

// 停止训练
const stopTraining = () => {
  if (!isTraining.value) return
  
  isTraining.value = false
  message.warning('训练已停止')
}

// 使用模型
const useModel = (model: any) => {
  message.success(`已选择模型: ${model.name}`)
  // 在实际应用中，这里会有使用模型的逻辑
}

// 导出模型
const exportModel = (model: any) => {
  message.success(`正在导出模型: ${model.name}`)
  // 在实际应用中，这里会有导出模型的逻辑
}

// 删除模型
const deleteModel = (model: any) => {
  trainedModels.value = trainedModels.value.filter(m => m.id !== model.id)
  message.success(`已删除模型: ${model.name}`)
}

// 显示入门教程
const showOnboarding = () => {
  message.info('显示训练入门教程')
  // 在实际应用中，这里会显示教程对话框
}

// 格式化时间（秒转为时:分:秒）
const formatTime = (seconds: number) => {
  if (seconds <= 0) return '00:00:00'
  
  const hours = Math.floor(seconds / 3600)
  const minutes = Math.floor((seconds % 3600) / 60)
  const secs = Math.floor(seconds % 60)
  
  return [
    hours.toString().padStart(2, '0'),
    minutes.toString().padStart(2, '0'),
    secs.toString().padStart(2, '0')
  ].join(':')
}

// 格式化日期
const formatDate = (date: Date) => {
  return date.toLocaleString('zh-CN', {
    year: 'numeric',
    month: 'numeric',
    day: 'numeric',
    hour: 'numeric',
    minute: 'numeric'
  })
}

// 获取随机颜色（根据ID生成一致的颜色）
const getRandomColor = (id: number) => {
  const colors = [
    '#2080f0', '#18a058', '#f0a020', '#d03050',
    '#7040f0', '#00b8c0', '#8c6428', '#707070'
  ]
  return colors[id % colors.length]
}

// 获取状态文本
const getStatusText = (status: string) => {
  const statusMap: Record<string, string> = {
    'ready': '就绪',
    'training': '训练中',
    'failed': '失败'
  }
  return statusMap[status] || status
}

// 获取类型文本
const getTypeText = (type: string) => {
  const typeMap: Record<string, string> = {
    'character': '角色模型',
    'scene': '场景模型',
    'action': '动作模型',
    'dialogue': '对话模型'
  }
  return typeMap[type] || type
}

// 返回上一页
const goBack = () => {
  router.back()
}
</script>

<style lang="scss" scoped>
.training-container {
  padding: 20px;
  height: 100%;
  overflow-y: auto;
  
  .training-card {
    .card-header {
      display: flex;
      justify-content: space-between;
      align-items: center;
      
      h1 {
        margin: 0;
        font-size: 24px;
        font-weight: 500;
      }
      
      .header-actions {
        display: flex;
        gap: 12px;
      }
    }
  }
  
  .content-layout {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 24px;
    margin-top: 20px;
    
    @media (max-width: 1200px) {
      grid-template-columns: 1fr;
    }
  }
  
  .settings-section {
    h3 {
      margin-top: 0;
      margin-bottom: 16px;
    }
  }
  
  .progress-section {
    h3 {
      margin-top: 0;
      margin-bottom: 16px;
    }
    
    .progress-info {
      padding: 16px;
      border: 1px solid var(--border-color);
      border-radius: 4px;
    }
    
    .progress-stats {
      display: flex;
      justify-content: space-between;
      margin-top: 16px;
      
      .stat-item {
        text-align: center;
        
        .stat-label {
          font-size: 12px;
          color: var(--text-color-3);
          margin-bottom: 4px;
        }
        
        .stat-value {
          font-size: 16px;
          font-weight: 500;
        }
      }
    }
    
    .metrics-charts {
      display: grid;
      grid-template-columns: 1fr 1fr;
      gap: 16px;
      margin-top: 16px;
      
      .chart-container {
        h4 {
          margin-top: 0;
          margin-bottom: 8px;
          font-size: 14px;
        }
        
        .chart-placeholder {
          height: 120px;
          background-color: var(--card-color);
          border: 1px dashed var(--border-color);
          border-radius: 4px;
          display: flex;
          justify-content: center;
          align-items: center;
          color: var(--text-color-3);
        }
      }
    }
    
    .training-logs {
      margin-top: 16px;
      
      h4 {
        margin-top: 0;
        margin-bottom: 8px;
        font-size: 14px;
      }
      
      .log-container {
        font-family: monospace;
        font-size: 12px;
        
        .log-item {
          padding: 4px 0;
          border-bottom: 1px solid var(--border-color);
          
          &:last-child {
            border-bottom: none;
          }
          
          .log-time {
            color: var(--text-color-3);
            margin-right: 8px;
          }
          
          .log-level {
            display: inline-block;
            padding: 1px 4px;
            border-radius: 2px;
            margin-right: 8px;
            font-size: 10px;
            
            &.log-level-info {
              background-color: var(--info-color);
              color: #fff;
            }
            
            &.log-level-warning {
              background-color: var(--warning-color);
              color: #fff;
            }
            
            &.log-level-error {
              background-color: var(--error-color);
              color: #fff;
            }
          }
        }
      }
    }
    
    .control-buttons {
      display: flex;
      justify-content: center;
      gap: 16px;
      margin-top: 20px;
    }
    
    .models-list {
      .model-meta {
        display: flex;
        align-items: center;
        gap: 8px;
        margin-bottom: 4px;
        
        .model-type {
          font-size: 12px;
          color: var(--text-color-3);
        }
        
        .model-meta-item {
          font-size: 12px;
          color: var(--text-color-3);
        }
      }
      
      .model-description {
        font-size: 13px;
        margin: 4px 0;
      }
      
      .model-actions {
        display: flex;
        gap: 8px;
      }
    }
    
    .training-tips {
      margin-top: 20px;
      
      h4 {
        margin-top: 0;
        margin-bottom: 12px;
        font-size: 16px;
      }
      
      ul {
        margin: 0;
        padding-left: 20px;
        
        li {
          margin-bottom: 8px;
          font-size: 14px;
          color: var(--text-color-2);
        }
      }
    }
  }
}
</style> 